package com.asiainfo.services;

import com.alibaba.fastjson.JSON;
import com.asiainfo.bean.ResponseBodyVo;
import com.asiainfo.bean.ResponseVo;
import com.asiainfo.http.HttpUtil;
import com.asiainfo.rsa.IOUtil;
import com.asiainfo.rsa.RSASignature;
import com.asiainfo.utils.ConfigurationUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * Created by ThinkPad on 2018/1/4.
 */
@Service("AuthService")
public class AuthService {

    private static Logger log = LoggerFactory.getLogger(AuthService.class);

    /**
     * 鉴权、授权查验
     */
    public String authCheck(String authKey, String authVal, String url) {
        String token = ConfigurationUtil.getToken();
        String content = requestParamToStr(token, authKey, authVal);
        log.info("request param:" + content);
        String privateKey = IOUtil.loadKeyByFile(ConfigurationUtil.getPrivateKeyPath());
        String signature = RSASignature.sign(content, privateKey);

        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("token", token);
        paramMap.put(authKey, authVal);
        paramMap.put("signature", signature);
        String result = "";
        try {
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("Content-Type", "application/json;charset=utf-8");
            headerMap.put("Accept", "application/json");
            result = HttpUtil.post(url, headerMap, paramMap);
        } catch (Exception e) {
            log.error("HTTP请求异常", e);
        }
        return result;
    }

    private String getSignContent(List<String> paramList) {
        Collections.sort(paramList);
        return String.join("&", paramList);
    }

    public boolean checkAuthResult(String result) {
        if (null == result || "".equals(result)) {
            return false;
        }
        try {
            ResponseVo responseVo = JSON.parseObject(result, ResponseVo.class);
            if (null == responseVo) {
                return false;
            }
            if (responseVo.getErrorCode() != 0) {
                return false;
            }
            ResponseBodyVo responseBodyVo = responseVo.getBody();
            String responseBodyVoStr = responseBodyVoToStr(responseBodyVo);
            log.info("response body content:" + responseBodyVoStr);
            String publicKey = IOUtil.loadKeyByFile(ConfigurationUtil.getPublicKeyPath());
            return RSASignature.doCheck(responseBodyVoStr, responseVo.getSignature(), publicKey);
        } catch (Exception e) {
            log.error("check fail", e);
        }
        return false;
    }

    public String responseBodyVoToStr(ResponseBodyVo responseBodyVo) {
        if (null == responseBodyVo) {
            return null;
        }
        List<String> bodyList = new ArrayList<>();
        bodyList.add("recordNo=" + responseBodyVo.getRecordNo());
        bodyList.add("encryptContent=" + responseBodyVo.getEncryptContent());
        bodyList.add("contentVer=" + responseBodyVo.getContentVer());
        bodyList.add("authorizeOrgNo=" + responseBodyVo.getAuthorizeOrgNo());
        bodyList.add("authorizeTime=" + responseBodyVo.getAuthorizeTime());
        bodyList.add("isVaild=" + responseBodyVo.isIsVaild());
        bodyList.add("auzCertificate=" + responseBodyVo.getAuzCertificate());
        bodyList.add("encryption=" + responseBodyVo.getEncryption());
        String authenticateOrgNo = responseBodyVo.getAuthenticateOrgNo();
        String authenticateTime = responseBodyVo.getAuthenticateTime();
        if (!StringUtils.isEmpty(authenticateOrgNo)) {
            bodyList.add("authenticateOrgNo=" + authenticateOrgNo);
        }
        if (!StringUtils.isEmpty(authenticateTime)) {
            bodyList.add("authenticateTime=" + authenticateTime);
        }
        return getSignContent(bodyList);
    }

    /**
     * 请求参数转LIST
     */
    public String requestParamToStr(String token, String authKey, String authVal) {
        List<String> paramList = new ArrayList<>();
        paramList.add("token=" + token);
        paramList.add(authKey + "=" + authVal);
        return getSignContent(paramList);
    }
}
